package com.roadmap.biz.message;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.roadmap.biz.common.BaseManager;
import com.roadmap.biz.common.RdcQueryConst;
import com.roadmap.common.BaseEntity;
import com.roadmap.common.RdcConst;
import com.roadmap.common.RdcLogger;
import com.roadmap.common.BaseEnum.ActionType;
import com.roadmap.entities.Comment;
import com.roadmap.entities.ext.CommentExt;
import com.roadmap.exception.ActionNotSupportedException;
import com.roadmap.exception.EntityNotFoundException;
import com.roadmap.exception.InvalidActionException;
import com.roadmap.exception.InvalidQueryException;
import com.roadmap.exception.InvalidValueException;
import com.roadmap.exception.NotAuthorizedException;
import com.roadmap.exception.NotMatchedException;
import com.roadmap.exception.NullObjectException;
import com.roadmap.exception.ServerException;
import com.roadmap.repo.db.RdcQuery;

public class CommentManager extends BaseManager {
	private final static Logger _log = RdcLogger
			.getLogger(CommentManager.class);

	public CommentManager(String aspirantId, String itemOwner) {
		super(aspirantId, itemOwner, Comment.class);
	}

	public CommentManager(String aspirantId, String itemOwner, Class parentClazz) {
		super(aspirantId, itemOwner, Comment.class, parentClazz);
	}

	@Override
	public void create(BaseEntity entity) throws NullObjectException,
			InvalidValueException, ServerException, InvalidActionException,
			EntityNotFoundException, ActionNotSupportedException,
			NotAuthorizedException {
		checkEntityIsValid(entity);
		getDbUtil().save(entity);

		Comment cmt = (Comment) entity;
		Class clazz = RdcConst.getEntityNameClazz(cmt.getEntryType());

		// 如果用户评论自己的item将不会有通知
		if (clazz != null && !cmt.getAuthorId().equals(cmt.getHostId())) {
			BaseEntity entry = getDbUtil()
					.getEntityById(clazz, cmt.getTypeId());

			// 对比entry的拥有者ID和评论的host ID，如果两者不匹配，说明该评论是回复
			getNoticeManager().notifyForEntry(entry, ActionType.COMMENT,
					cmt.getHostId());
		}
	}

	@Override
	public List getEntitiesOfParent(String parentId) throws ServerException,
			NullObjectException, NotMatchedException, InvalidValueException,
			InvalidQueryException, EntityNotFoundException,
			NotAuthorizedException {
		if (parentId == null) {
			NullObjectException e = new NullObjectException();
			_log.error("parentId is null.", e);
			throw e;
		}

		RdcQuery query = getDbUtil().createNativeSQLQuery(
				RdcQueryConst.SQL_COMMENTS_ORDERBY_TIME);
		query.addEntity("c", Comment.class);
		query.setParameter("tid", parentId);
		query.addScalar("realName");
		List<Object[]> results = query.getResults();
		if (results == null || results.isEmpty()) {
			return null;
		}

		results = getResultsForSpecifiedPage(results);

		List<CommentExt> comments = new ArrayList<CommentExt>();
		Iterator<Object[]> iter = results.iterator();
		while (iter.hasNext()) {
			Object[] result = (Object[]) iter.next();
			CommentExt cmt = new CommentExt((Comment) result[0]);
			cmt.setAuthorName((String) result[1]);
			comments.add(cmt);
		}

		return comments;
	}

	@Override
	public void delete(String entryId) throws NullObjectException,
			ServerException, InvalidValueException, InvalidActionException,
			EntityNotFoundException, NotAuthorizedException,
			ActionNotSupportedException {
		Comment cmt = (Comment) get(entryId);
		if (cmt == null) {
			EntityNotFoundException e = new EntityNotFoundException();
			_log.error(String.format("Comment %s was not found", entryId), e);
			throw e;
		}

		getDbUtil().delete(cmt);
	}

	@Override
	public BaseEntity getEntityExt(String entryId) throws NullObjectException,
			InvalidQueryException, ServerException, InvalidValueException,
			EntityNotFoundException, NotMatchedException,
			NotAuthorizedException, ActionNotSupportedException {
		Comment cmt = (Comment) get(entryId);
		if (cmt == null) {
			EntityNotFoundException e = new EntityNotFoundException();
			_log.error(String.format("Comment %s was not found", entryId), e);
			throw e;
		}

		String hql = String.format("from %s where id=?", cmt.getEntryType());
		BaseEntity parent = (BaseEntity) getDbUtil().getUniqueEntity(hql,
				new Object[] { cmt.getTypeId() });
		if (parent == null) {
			EntityNotFoundException e = new EntityNotFoundException();
			_log.error(String.format("%s %s was not found", cmt.getEntryType(),
					cmt.getTypeId()), e);
			throw e;
		}
		
		CommentExt ext = new CommentExt(cmt);
		ext.setParentDesc(parent.getWhatItIs());

		return ext;
	}
}
